---动作管理类，该类维护代理身上的所有动作
---@class ActionManagerBase
---@field actionHandlerDic table<string,ActionHandlerBase>  动作标签和动作的键值
---@field syneActionHandlers table<string,ActionHandlerBase>    同时执行的动作集合
---@field interruptibleHandlers ActionHandlerBase[]     能够打断计划的动作
---@field actionFsm GOAPFSM     简单动作状态机
---@field actionSyneFsm GOAPFSM 同时执行的动作状态机
---@field agent AgentBase   代理
---@field isPerformAction  boolean  当前是否在执行动作的标志位
---@field effectsAndActionMap table<string, ActionHandlerBase[]>    效果的键值和动作的映射关系
---@field onActionComplete function 动作执行完成回调
---@field base ActionManagerBase
ActionManagerBase = class()

function ActionManagerBase:ctor(agent)
    self.base = ActionManagerBase;
   self.agent = agent;
    self.actionHandlerDic = {}
    self.syneActionHandlers = {}
    self.interruptibleHandlers = {}
    self.actionFsm = GOAPFSM.new();
    self.actionSyneFsm = GOAPSyneFSM.new();
    self:InitActionHandlers();
    self:InitSyneActionHandlers();
    self:InitFsm();
    self:InitActionSyneFSM();
    self:InitEffectsAndActionMap();
    self:InitInterruptibleDic();
end

---初始化动作列表，子类重写
function ActionManagerBase:InitActionHandlers() end

---初始化同时执行的动作列表，子类重写
function ActionManagerBase:InitSyneActionHandlers() end

---获取默认动作的标签，子类重写
function ActionManagerBase:GetDefaultActionLabel() end

---初始化状态机
function ActionManagerBase:InitFsm()
    for k, v in pairs(self.actionHandlerDic) do
        self.actionFsm:AddState(k,v);
    end
end

---初始化同步执行动作的状态机
function ActionManagerBase:InitActionSyneFSM()
    for k, v in pairs(self.syneActionHandlers) do
        self.actionSyneFsm:AddState(k,v);
    end
end

---初始化影响与动作的键值对
function ActionManagerBase:InitEffectsAndActionMap()
    self.effectsAndActionMap = {}
    for k, v in pairs(self.actionHandlerDic) do
        if v.action.effects ~= nil then
            for m, n in pairs(v.action.effects.dataTable) do
                if self.effectsAndActionMap[m] == nil then
                    self.effectsAndActionMap[m] = {}
                end
                table.insert(self.effectsAndActionMap[m],v);
            end
        else
            Debug.LogWarning("警告:动作"..v.action.label.."的影响是nil");
        end
    end
end

---初始化可打断的动作列表
function ActionManagerBase:InitInterruptibleDic()
    for k, v in pairs(self.actionHandlerDic) do
        if v.action.canInterruptiblePlan then
            table.insert(self.interruptibleHandlers,v);
        end
    end
    table.sort(self.interruptibleHandlers,function (a,b)
        return a.action.priority > b.action.priority
    end)
end

---@param label string
---@param dic table<string,ActionHandlerBase>
function ActionManagerBase:AddHandler(label, dic)
    local handler = self.agent.dataMap:GetActionHandler(label);
    if handler ~= nil then
        if dic[label] ~= nil then
            Debug.LogError("动作标签"..label.."在动作管理器中已经存在，不能重复添加动作！")
        end
        dic[label] = handler;
        handler:SetFinishCallFunc(function (actionLable)
            if self.onActionComplete ~= nil then
                self.onActionComplete(actionLable);
            end
        end)
    else
        Debug.LogError("映射文件中未找到对应Handler,标签为："..label);
    end
end

---添加动作
---@param label string
function ActionManagerBase:AddActionHandler(label)
    self:AddHandler(label,self.actionHandlerDic);
end

---添加同步执行动作
---@param label string
function ActionManagerBase:AddSyneActionHandler(label)
    self:AddHandler(label,self.syneActionHandlers);
end

---移除动作
---@param label string
function ActionManagerBase:RemoveHandler(label)
    self.actionHandlerDic[label] = nil;
end

---根据标签获取handler
---@param label string
function ActionManagerBase:GetHandler(label)
    if self.actionHandlerDic[label] == nil then
        Debug.LogError("尝试获取动作:"..label.."失败，该动作未添加到ActionManager")
        return nil;
    end
    return self.actionHandlerDic[label];
end

---帧函数
function ActionManagerBase:FrameFun()
    if self.isPerformAction then
        self.actionFsm:FrameFun();
    end
    self.actionSyneFsm:FrameFun();
end

---数据更新函数
function ActionManagerBase:UpdateData()
    self:JudgeInterruptibleHandler();
    self:JudgeConformActionSyne();
end

---判断是否有能够打断计划的动作执行
function ActionManagerBase:JudgeInterruptibleHandler()
    for i, v in ipairs(self.interruptibleHandlers) do
        if v:CanPerformAction() then
            Debug.Log(v.label.."打断计划");
            self.agent.performer:Interruptible();
            break;
        end
    end
end

---判断是否有满足条件的可叠加动作执行
function ActionManagerBase:JudgeConformActionSyne()
    for k, v in pairs(self.syneActionHandlers) do
        if self.agent.agentState:ContainState(v.action.preconditions)
            and (v.excuteState == EActionExcuteState.INIT or v.excuteState == EActionExcuteState.EXIT) then
            self:ExcuteNewState(k);
        end
    end
end

---执行动作
---@param lable string
function ActionManagerBase:ExcuteNewState(lable)
    if self.actionHandlerDic[lable] ~= nil then
        self.actionFsm:ExcuteNewState(lable);
    elseif self.syneActionHandlers[lable] ~= nil then
        self.actionSyneFsm:ExcuteNewState(lable);
    else
        Debug.LogError("动作"..lable.."不在ActionManager缓存内，无法执行");
    end
end

---设置动作执行完成的回调
function ActionManagerBase:SetActionComplenteCallFunc(callfunc)
    self.onActionComplete = callfunc;
end